home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / p4 / p4-1_2c.lha / p4-1.2c / lib / p4_rm.c < prev    next >
C/C++ Source or Header  |  1993-06-14  |  13KB  |  438 lines

  1. #include "p4.h"
  2. #include "p4_sys.h"
  3.  
  4. /*
  5.   Defining REDIRECT_OUTPUT allows you to redirect output from
  6.   processes as follows.
  7.   Defining OUT_TO_TERM tty allows you to redirect the
  8.   output from various processes to separate windows.
  9.   */
  10.  
  11. #if defined(REDIRECT_OUTPUT)
  12. #if defined(OUT_TO_TERM)
  13. #define P4_OUTFILE "/dev/ttyp4"
  14. #else
  15. #define P4_OUTFILE "/u/rbutler/p4/tests/out"
  16. #endif
  17. #endif
  18.  
  19. static int rm_num;
  20. static int rm_flag;
  21.  
  22. int rm_start(argc, argv)
  23. int *argc;
  24. char **argv;
  25. {
  26.     int bm_fd, bm_port;
  27.     char *s,*bm_host;
  28.     extern char whoami_p4[];
  29.     struct net_initial_handshake hs;
  30.     struct slave_listener_msg lmsg;
  31.     struct bm_rm_msg msg;
  32.     int type, rc, i, numslaves;
  33.     struct p4_global_data *g;
  34.     char outfile[128];
  35.  
  36.     trap_sig_errs();         /* Errors can happen any time */
  37.  
  38.     sprintf(whoami_p4, "rm_%d", getpid());
  39.     p4_dprintfl(20,"remote master starting\n");
  40.  
  41. #if defined(REDIRECT_OUTPUT)
  42.     freopen(P4_OUTFILE, "w", stdout);
  43.     freopen(P4_OUTFILE, "w", stderr);
  44. #endif
  45.  
  46.     if (*argc < 4)
  47.     p4_error("Invalid arguments to remote_master", *argc);
  48.  
  49.     bm_host = argv[1];
  50.     bm_port = atoi(argv[2]);
  51.  
  52.     bm_fd = net_conn_to_listener(bm_host, bm_port, 5);
  53.     if (bm_fd < 0)
  54.     p4_error("rm_start: net_conn_to_listener failed", bm_port);
  55.  
  56.     net_recv(bm_fd, &hs, sizeof(hs));
  57.     hs.pid = (int) htonl(getpid());
  58.     net_send(bm_fd, &hs, sizeof(hs), FALSE);
  59.  
  60. #   ifdef SYSV_IPC
  61.     sysv_num_shmids = 0;
  62.     sysv_shmid[0]  = -1;
  63.     sysv_semid0    = -1;
  64.     sysv_semid0 = init_sysv_semset(0);
  65. #   endif
  66.  
  67.     /* Get the initialization information from the bm */
  68.  
  69.     rc = net_recv(bm_fd, &msg, sizeof(msg));
  70.     if (rc == PRECV_EOF)
  71.     p4_error("rm_start: got EOF on net_recv", bm_fd);
  72.     type = p4_n_to_i(msg.type);
  73.     if (type != INITIAL_INFO)
  74.     p4_error("rm_start: unknown type, expecting INITIAL_INFO, type=", type);
  75.     if (strcmp(msg.version,p4_version()) != 0)
  76.     {
  77.     p4_dprintf("my version is %s\n",p4_version());
  78.     p4_error("version does not match master \n",0);
  79.     }
  80.  
  81.     if ((s = (char *) rindex(msg.pgm,'/'))  !=  NULL)
  82.     {
  83.     *s = '\0';  /* chg to directory name only */
  84.     chdir(msg.pgm);
  85.     }
  86.  
  87.     globmemsize = p4_n_to_i(msg.memsize);
  88.     logging_flag = p4_n_to_i(msg.logging_flag);
  89.     if (logging_flag)
  90.     ALOG_ENABLE;
  91.     else
  92.     ALOG_DISABLE;
  93.  
  94.     MD_initmem(globmemsize);
  95.     alloc_global();  /* sets p4_global */
  96.     g = p4_global;
  97.     p4_local = alloc_local_rm();
  98.     g->local_communication_only = FALSE;
  99.     g->num_in_proctable = p4_n_to_i(msg.numinproctab);
  100.     numslaves = p4_n_to_i(msg.numslaves);
  101.     rm_num = p4_n_to_i(msg.rm_num);
  102.     debug_level = p4_n_to_i(msg.debug_level);
  103.     strcpy(outfile, msg.outfile);
  104.     strcpy(p4_global->application_id, msg.application_id);
  105.     p4_dprintfl(90, "got numslaves=%d outfile=%s rm_num=%d dbglvl=%d appid=%s\n",
  106.         numslaves, outfile, rm_num, debug_level, msg.application_id);
  107.  
  108.     MD_initenv();
  109.     usc_init();
  110.  
  111.     if (*outfile)
  112.     {
  113.     freopen(outfile, "w", stdout);
  114.     freopen(outfile, "w", stderr);
  115.     }
  116.  
  117.     SIGNAL_P4(LISTENER_ATTN_SIGNAL, handle_connection_interrupt);
  118.     p4_lock(&g->slave_lock);
  119.     create_rm_processes(numslaves, bm_fd);
  120.     if (!rm_flag) /* I am not rm; was forked in create_rm_processes */
  121.     return(0);
  122.  
  123.     /* Grab the whole proc table from the bm */
  124.     p4_dprintfl(90, "receiving proc table\n");
  125.     receive_proc_table(bm_fd);
  126.  
  127.     /* let local slaves use proctable to identify themselves */
  128.     p4_unlock(&g->slave_lock);
  129.  
  130.     sprintf(whoami_p4, "rm_%d_%d", rm_num, getpid());
  131.     p4_local->my_id = p4_get_my_id_from_proc();
  132.  
  133.     p4_global->low_cluster_id = 
  134.     p4_local->my_id - p4_global->proctable[p4_local->my_id].slave_idx;
  135.     p4_global->hi_cluster_id = 
  136.     p4_global->low_cluster_id + p4_global->local_slave_count;
  137.  
  138.     setup_conntab();
  139.  
  140.     if (p4_local->conntab[0].type == CONN_REMOTE_SWITCH)
  141.     {
  142.     p4_local->conntab[0].switch_port = p4_global->proctable[0].switch_port;
  143.     p4_local->conntab[0].port = bm_fd;
  144.     }
  145.     else if (p4_local->conntab[0].type == CONN_REMOTE_NON_EST)
  146.     {
  147.     p4_local->conntab[0].type = CONN_REMOTE_EST;
  148.     p4_local->conntab[0].port = bm_fd;
  149.     p4_local->conntab[0].same_data_rep =
  150.         same_data_representation(p4_local->my_id,0);
  151.     }
  152.     else
  153.     {
  154.     p4_error("rm_start: invalid conn type in conntab ",
  155.          p4_local->conntab[0].type);
  156.     }
  157.  
  158.     sprintf(whoami_p4, "p%d_%d", p4_get_my_id(), getpid());
  159.  
  160.  
  161. #if defined(IPSC860)  ||  defined(CM5)  ||  defined(NCUBE)
  162.     for (i = 1; i < numslaves; i++)
  163.     {
  164. #       if defined(IPSC860)
  165.     csend((long) INITIAL_INFO, &msg, (long) sizeof(struct bm_rm_msg), 
  166.               (long) i, (long) NODE_PID);
  167.     csend((long) INITIAL_INFO, p4_global->proctable, 
  168.               (long) sizeof(p4_global->proctable), (long) i, (long) NODE_PID);
  169. #       endif
  170. #       if defined(CM5)
  171.     CMMD_send_noblock(i, INITIAL_INFO,  &msg,sizeof(struct bm_rm_msg));
  172.     CMMD_send_noblock(i, INITIAL_INFO,  p4_global->proctable, 
  173.                           sizeof(p4_global->proctable));
  174. #       endif
  175. #       if defined(NCUBE)
  176.     nwrite(&msg, sizeof(struct bm_rm_msg), i, INITIAL_INFO, &unused_flag);
  177.     nwrite(p4_global->proctable, sizeof(p4_global->proctable), i, INITIAL_INFO, &unused_flag);
  178. #       endif
  179.     }
  180. #endif
  181.  
  182.     /* 
  183.        sync with local slaves thus insuring that they have the proctable before 
  184.        syncing with bm (this keeps bm and its slaves  from interrupting the local 
  185.        processes too early; then re-sync with local slaves (thus permitting them to 
  186.        interrupt remotes)
  187.     */
  188.     p4_barrier(&(p4_global->cluster_barrier),p4_num_cluster_ids());
  189.     
  190.     msg.type = p4_i_to_n(SYNC_MSG);
  191.     net_send(bm_fd, &msg, sizeof(msg), FALSE);
  192.     msg.type = -1;  /* reset to verify type received next */
  193.     rc = net_recv(bm_fd, &msg, sizeof(msg));
  194.     type = p4_n_to_i(msg.type);
  195.     if (type != SYNC_MSG)
  196.     p4_error("rm_start: unknown type, expecting SYNC_MSG, type=", type);
  197.     
  198.     p4_barrier(&(p4_global->cluster_barrier),p4_num_cluster_ids());
  199.  
  200.     return(0);
  201. }
  202.  
  203.  
  204. P4VOID create_rm_processes(nslaves, bm_fd)
  205. int nslaves;
  206. int bm_fd;
  207. {
  208.     struct p4_global_data *g = p4_global;
  209.     struct listener_data *l;
  210.     int end_1, end_2, slave_pid, listener_pid;
  211.     int slave_idx, listener_port, listener_fd;
  212.     char rm_host[100];
  213.     int i, rm_switch_port, from;
  214.     struct bm_rm_msg bm_msg;
  215.  
  216. #   if !defined(IPSC860)  &&  !defined(CM5)  &&  !defined(NCUBE)
  217.     if (nslaves > P4_MAX_MSG_QUEUES)
  218.     p4_error("create_rm_processes: more slaves than msg queues \n", nslaves);
  219. #   endif
  220.  
  221.     rm_flag = 0;  /* set below for the remote master */
  222.     /*
  223.      * Allocate the listener's local data area, since this process will
  224.      * eventually become the listener.
  225.      */
  226.  
  227.     l = listener_info = alloc_listener_info();
  228.  
  229.     net_setup_anon_listener(10, &listener_port, &listener_fd);
  230.  
  231.     p4_dprintfl(70, "created listener on port %d fd %d\n", listener_port,
  232.         listener_fd);
  233.  
  234.     /* Send off the listener info to the bm */
  235.     bm_msg.type = p4_i_to_n(REMOTE_LISTENER_INFO);
  236.     bm_msg.port = p4_i_to_n(listener_port);
  237.     net_send(bm_fd, &bm_msg, sizeof(struct bm_rm_msg), FALSE);
  238.  
  239.     rm_host[0] = '\0';
  240.     get_qualified_hostname(rm_host);
  241.     rm_switch_port = getswport(rm_host);
  242.  
  243.     /* Send my info to the bm */
  244.     bm_msg.type = p4_i_to_n(REMOTE_MASTER_INFO);
  245.     bm_msg.slave_idx = p4_i_to_n(0);
  246.     bm_msg.slave_pid = p4_i_to_n(getpid());
  247.     bm_msg.switch_port = p4_i_to_n(rm_switch_port);
  248.     strcpy(bm_msg.host_name,rm_host);
  249.     strcpy(bm_msg.machine_type,P4_MACHINE_TYPE);
  250.     net_send(bm_fd, &bm_msg, sizeof(struct bm_rm_msg), FALSE);
  251.  
  252.     g->local_slave_count = 0;
  253.  
  254. #   ifdef TCMP
  255.     tcmp_init(NULL,p4_get_my_cluster_id(),shmem_getclunid());
  256. #   endif
  257.  
  258. #   if defined(IPSC860)  ||  defined(CM5)  ||  defined(NCUBE)
  259.     for (slave_idx = 1; slave_idx <= nslaves - 1; slave_idx++)
  260.     {
  261. #       if defined(IPSC860)
  262.     crecv(INITIAL_INFO, &bm_msg, (long) sizeof(struct bm_rm_msg));
  263. #       endif
  264. #       if defined(CM5)
  265.         CMMD_receive(CMMD_ANY_NODE, INITIAL_INFO, (void *) &bm_msg, 
  266.                      sizeof(struct bm_rm_msg));
  267. #       endif
  268. #       if defined(NCUBE)
  269.         from = NCUBE_ANY_NODE;
  270.         type = INITIAL_INFO;
  271.         nread(&bm_msg, sizeof(struct bm_rm_msg), &from,  &type, &unused_flag);
  272. #       endif
  273.     net_send(bm_fd, &bm_msg, sizeof(struct bm_rm_msg), FALSE);
  274.     g->local_slave_count++;
  275.     }
  276. #   else
  277.  
  278.     get_pipe(&end_1, &end_2);
  279.     for (slave_idx = 1; slave_idx <= nslaves - 1; slave_idx++)
  280.     {
  281.     p4_dprintfl(20,"remote master creating local slave %d\n",slave_idx);
  282.             
  283.     slave_pid = fork_p4();
  284.     if (slave_pid)
  285.         p4_dprintfl(10,"remote master created local slave %d\n",slave_idx);
  286.     if (slave_pid == 0)
  287.     {
  288.         /* In the slave process */
  289.  
  290.         sprintf(whoami_p4, "rm_s_%d_%d_%d", rm_num, slave_idx, getpid());
  291.  
  292.         close(listener_fd);
  293.         p4_local = alloc_local_slave();
  294.         p4_local->listener_fd = end_1;
  295.         close(end_2);
  296.  
  297.             SIGNAL_P4(LISTENER_ATTN_SIGNAL, handle_connection_interrupt);
  298.  
  299.  
  300.         /* hang for a valid proctable */
  301.         p4_lock(&g->slave_lock);
  302.         p4_unlock(&g->slave_lock);
  303.  
  304.         p4_local->my_id = p4_get_my_id_from_proc();
  305.         sprintf(whoami_p4, "p%d_%d", p4_get_my_id(), getpid());
  306.         setup_conntab();
  307.         usc_init();
  308.  
  309. #           ifdef TCMP
  310.             tcmp_init(NULL,p4_get_my_cluster_id(),shmem_getclunid());
  311. #           endif
  312.  
  313.         /* 
  314.            sync with local master twice: once to make sure all slaves 
  315.            have got proctable, and second after the master has synced bm
  316.         */
  317.         p4_barrier(&(p4_global->cluster_barrier),p4_num_cluster_ids());
  318.         p4_barrier(&(p4_global->cluster_barrier),p4_num_cluster_ids());
  319.  
  320.         p4_dprintfl(20, "remote process starting\n");
  321.             ALOG_SETUP(p4_local->my_id,ALOG_TRUNCATE);
  322.             ALOG_LOG(p4_local->my_id,BEGIN_USER,0,"");
  323.         return;
  324.     }
  325.  
  326.     /* Send off the slave info to the bm */
  327.     bm_msg.type = p4_i_to_n(REMOTE_SLAVE_INFO);
  328.     bm_msg.slave_idx = p4_i_to_n(slave_idx);
  329.     bm_msg.slave_pid = p4_i_to_n(slave_pid);
  330.     bm_msg.switch_port = p4_i_to_n(rm_switch_port);
  331.     strcpy(bm_msg.machine_type,P4_MACHINE_TYPE);
  332.     net_send(bm_fd, &bm_msg, sizeof(struct bm_rm_msg), FALSE);
  333.  
  334.     g->local_slave_count++;
  335.     }
  336. #endif
  337.  
  338.     /* Send the end message to the bm */
  339.     bm_msg.type = p4_i_to_n(REMOTE_SLAVE_INFO_END);
  340.     net_send(bm_fd, &bm_msg, sizeof(struct bm_rm_msg), FALSE);
  341.  
  342.     /*
  343.      * Done creating slaves. Now fork off the listener .. we've already
  344.      * created the socket and bound a port to it
  345.      */
  346.  
  347. #   if !defined(IPSC860)  &&  !defined(CM5)  &&  !defined(NCUBE)
  348.     g->listener_port = listener_port;
  349.     p4_local->listener_fd = end_1;
  350.     listener_pid = fork_p4();
  351.     if (listener_pid == 0)
  352.     {
  353.     /* Inside listener */
  354.     sprintf(whoami_p4, "rm_l_%d_%d", rm_num, getpid());
  355.     p4_dprintfl(70, "inside listener pid %d\n", getpid());
  356.     p4_local = alloc_local_listener();
  357.     l->listening_fd = listener_fd;
  358.     l->slave_fd = end_2;
  359.     close(end_1);
  360.     {
  361.         /* exec external listener process */
  362.  
  363.         char *listener_prg = LISTENER_PATHNAME;
  364.  
  365.         if (*listener_prg)
  366.         {
  367.         char dbg_c[10], max_c[10], lfd_c[10], sfd_c[10];
  368.  
  369.         sprintf(dbg_c, "%d", debug_level);
  370.         sprintf(max_c, "%d", p4_global->max_connections);
  371.         sprintf(lfd_c, "%d", l->listening_fd);
  372.         sprintf(sfd_c, "%d", l->slave_fd);
  373.         p4_dprintfl(70, "exec %s %s %s %s %s\n",
  374.                 listener_prg, dbg_c, max_c, lfd_c, sfd_c);
  375.         execlp(listener_prg, listener_prg,
  376.                dbg_c, max_c, lfd_c, sfd_c, NULL);
  377.         p4_dprintfl(70, "exec failed (errno= %d), using buildin\n",
  378.                 errno);
  379.         }
  380.     }
  381.     listener();
  382.     exit(0);
  383.     }
  384.  
  385.     /* Else we're still in the remote master */
  386.  
  387.     p4_dprintfl(70, "created listener pid %d\n", listener_pid);
  388.     /* We need to close the fds from the listener setup */
  389.     close(listener_fd);
  390.     close(end_2);
  391.     g->listener_pid = listener_pid;
  392. #   endif
  393.     rm_flag = 1;  /* I am the remote master */
  394. }
  395.  
  396.  
  397. P4VOID receive_proc_table(bm_fd)
  398. int bm_fd;
  399. {
  400.     P4BOOL done;
  401.     struct bm_rm_msg msg;
  402.     int type;
  403.     int port, unix_id, slave_idx, group_id;
  404.     int switch_port;
  405.  
  406.     p4_dprintfl(90, "receive_proc_table\n");
  407.     for (done = FALSE; !done;)
  408.     {
  409.     if (net_recv(bm_fd, &msg, sizeof(msg)) == PRECV_EOF)
  410.         p4_error("recv_proc_table: got net_send_eof", bm_fd);
  411.  
  412.     type = p4_n_to_i(msg.type);
  413.     switch (type)
  414.     {
  415.       case PROC_TABLE_ENTRY:
  416.         group_id = p4_n_to_i(msg.group_id);
  417.         port = p4_n_to_i(msg.port);
  418.         unix_id = p4_n_to_i(msg.unix_id);
  419.         slave_idx = p4_n_to_i(msg.slave_idx);
  420.         switch_port = p4_n_to_i(msg.switch_port);
  421.         p4_dprintfl(90, "got entry gid=%d host=%s port=%d unix_id=%d slave_idx=%d switch_port=%d\n",
  422.             group_id,msg.host_name,port,unix_id,slave_idx,switch_port);
  423.         /* remote master loading proctable from big master */
  424.         install_in_proctable(group_id, port, unix_id, msg.host_name,
  425.                  slave_idx, msg.machine_type, switch_port);
  426.         break;
  427.  
  428.       case PROC_TABLE_END:
  429.         done = TRUE;
  430.         break;
  431.  
  432.       default:
  433.         p4_dprintf("receive_proc_table: got invalid message type %d\n", type);
  434.         break;
  435.     }
  436.     }
  437. }
  438.